<template>
  <div>
    <el-tabs closable
             v-model="editableTabsValue"
             type="border-card"
             @tab-remove="removeTab"
             :height="taskProcessTableHeight">
      <el-tab-pane name="-1"
                   :height="taskProcessTableHeight">
        <span slot="label"><i v-if="myJob.iconClass"
             :class="myJob.iconClass"></i><i v-else
             class="el-icon-s-operation"></i>任务记录</span>
        <el-card shadow="never">
          <div slot="header">
            <el-row>
              <el-col :span="24">
                <el-tag>{{myJob.jobName}}</el-tag>
                <el-divider direction="vertical"></el-divider>
                <el-tag>
                  <i class="el-icon-star-on"></i>
                  {{currentProcessId}}
                </el-tag>
                <el-checkbox v-model="checkedRefresh"
                             @change="checkBoxRefreshChange">实时刷新</el-checkbox>
                </el-button>
                <el-popconfirm title="将为该作业组生成新的任务，确定吗？"
                               confirmButtonText='确定'
                               cancelButtonText='点错了，不要执行'
                               icon="el-icon-info"
                               iconColor="red"
                               @onConfirm="handleJobGroupNewTask()">
                  <el-button :disabled="checkCreateNewDisabled(currentProcessStatus) || myJob.izEnabled == '0'"
                             circle
                             size="mini"
                             slot="reference"
                             type="success"
                             plain>启动新任务</el-button>
                </el-popconfirm>
                <el-popconfirm title="将为当前任务组下所有在运行的任务发送停止命令，确定吗？"
                               confirmButtonText='确定'
                               cancelButtonText='点错了，不要停止'
                               icon="el-icon-info"
                               iconColor="red"
                               @onConfirm="handleJobGroupStopTask()">
                  <el-button :disabled="!checkCreateNewDisabled(currentProcessStatus)"
                             circle
                             size="mini"
                             slot="reference"
                             type="success"
                             plain>停止当前任务</el-button>
                </el-popconfirm>
                <el-divider direction="vertical"></el-divider>
                <el-button circle
                           size="mini"
                           type="success"
                           plain
                           @click="handleListTaskBefore()">向前翻页</el-button>
                <el-button circle
                           size="mini"
                           type="success"
                           plain
                           @click="handleListTaskAfter()">向后翻页</el-button>
              </el-col>
            </el-row>
          </div>
          <el-table :data="myJob.taskProcesses"
                    ref="taskProcessesTable"
                    border
                    row-key="id"
                    sortable
                    :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
                    :height="taskProcessTableHeight"
                    style="width: 100%">
            <el-table-column fixed
                             label="作业名称"
                             width="260">
              <template slot-scope="{row}">
                <i class="el-icon-star-on"
                   v-if="row.id == currentProcessId"></i>
                {{row.jobName}}
              </template>
            </el-table-column>
            <el-table-column label="任务ID"
                             fixed
                             align="center"
                             width="100">
              <template slot-scope="{row}">
                {{row.id}}
              </template>
            </el-table-column>
            <el-table-column label="计划时间"
                             align="center"
                             prop="scheduleTime"
                             width="160">
              <template slot-scope="{row}">
                {{formatTime(row.scheduleTime)}}
              </template>
            </el-table-column>
            <el-table-column label="运行状态"
                             align="center"
                             width="100">
              <template slot-scope="{row}">
                {{getDictLabel('task_status', row.status)}}
              </template>
            </el-table-column>
            <el-table-column label="日志"
                             align="center"
                             width="50">
              <template slot-scope="{row}">
                <!-- {{ row.logFileName}} -->
                <el-button v-if="row.logFileName !=null && row.logFileName !=''"
                           size="mini"
                           type="success"
                           icon="el-icon-tickets"
                           plain
                           circle
                           @click="handleLogFile(row)">
                </el-button>
                <template v-else>N/A</template>
              </template>
            </el-table-column>
            <el-table-column label="开始运行时间"
                             align="center"
                             width="160">
              <template slot-scope="{row}">
                {{formatTime(row.startTime)}}
              </template>
            </el-table-column>
            <el-table-column label="结束运行时间"
                             align="center"
                             width="160">
              <template slot-scope="{row}">
                {{formatTime(row.stopTime)}}
              </template>
            </el-table-column>
            <el-table-column label="创建类型"
                             width="100">
              <template slot-scope="{row}">
                {{ getDictLabel('create_mode', row.createMode)}}
              </template>
            </el-table-column>
            <el-table-column label="运行主机"
                             width="120">
              <template slot-scope="{row}">
                {{ row.hostName}}
              </template>
            </el-table-column>
            <el-table-column label="动作类型"
                             align="center"
                             width="80">
              <template slot-scope="{row}">
                {{ getDictLabel('action_type', row.actionType)}}
              </template>
            </el-table-column>
            <el-table-column label="计划名称"
                             width="160">
              <template slot-scope="{row}">
                {{ row.crontabName}}
              </template>
            </el-table-column>
            <el-table-column label="进程号"
                             width="100">
              <template slot-scope="{row}">
                {{ row.instancePid}}
              </template>
            </el-table-column>
            <el-table-column label="返回码"
                             width="100">
              <template slot-scope="{row}">
                {{ row.returnCode}}
              </template>
            </el-table-column>
            <el-table-column label="启动命令"
                             width="360">
              <template slot-scope="{row}">
                {{ row.startCommand}}
              </template>
            </el-table-column>
            <el-table-column label="停止命令"
                             width="260">
              <template slot-scope="{row}">
                {{ row.stopCommand}}
              </template>
            </el-table-column>
            <el-table-column label="备注"
                             width="480">
              <template slot-scope="{row}">
                {{ row.remark}}
              </template>
            </el-table-column>
          </el-table>
          <!-- 任务记录 END. -->
        </el-card>
      </el-tab-pane>
      <!-- :label="'日志:'+item.id" -->
      <el-tab-pane v-for="(item, index) in myLogFileList"
                   :key="item.id"
                   :name="''+item.id">
        <span slot="label"><i v-if="item.iconClass"
             :class="item.iconClass"></i>日志:{{item.id}}</span>
        <task-log-file :myLogFile="item"></task-log-file>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script>
import { formatDate } from "@/utils/date";
import { hasPermission, getEntries, getLabel } from "@/utils/dict";
import { apiTaskCreate, apiTaskGroupStop, apiTaskCurrentGroup, apiChildrenTaskList, apiTaskRefresh } from "@/api/monitor";
import TaskLogFile from "./TaskLogFile";

export default {
  name: "JobGroupExecutor",
  components: { TaskLogFile },
  props: {
    myJob: {
      jobName: '默认值',
      izEnabled: '0'
    }
  },
  data() {
    return {
      editableTabsValue: '-1',
      checkedRefresh: false,
      refreshEndTime: null,
      currentProcessId: 0,
      currentProcessStatus: null,
      intervalReader: null,
      cfgJobList: [],
      multipleCrontabSelection: [],
      multipleDependenceSelection: [],
      myLogFileList: [],
      listLoading: false,
      conheight: {
        height: ''
      },
      crontabTableHeight: 300,
      cfgJogTableHeight: 500,
      taskProcessTableHeight: 460,
      consoleOn: false,
      textarea: '',
      defaultNewCrontab: {
        id: null,
        jobId: null,
        actionType: '0',
        schedulerType: '1',
        actionTime: null,
        izEnabled: '0',
        minute: '*',
        hour: '*',
        day: '*',
        weekday: '*',
        month: '0',
        runDuration: 180,
        name: '默认值,修改我吧',
        remark: '备注, 详细说明调度计划',
      },
    };
  },

  created() {
    //this.callCfgJobList();
    window.addEventListener('resize', this.getHeight);
    this.getHeight();
    this.getTaskProcessList(this.myJob);

  },

  destroyed() {
    if (this.intervalReader) {
      clearInterval(this.intervalReader);
      this.intervalReader = null;
    }
  },


  methods: {
    hasPermission(url) {
      return hasPermission(url)
    },
    getOptions(dictKey) {
      return getEntries(dictKey);
    },

    getDictLabel(dictKey, dictValue) {
      return getLabel(dictKey, dictValue);
    },

    formatTime(time) {
      if (time == null || time === '') {
        return 'N/A';
      }
      let date = new Date(time);
      return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
    },

    getHeight() {
      //this.myHeight = window.innerHeight - 100;
      this.conheight.height = window.innerHeight - 100 + 'px';
      //this.jobTableHeight = window.innerHeight - 100 - 140 + 'px';
    },

    removeTab(targetName) {
      if ('-1' == targetName) {
        return;
      }

      let tabs = this.myLogFileList;
      let activeName = this.editableTabsValue;
      if (activeName == targetName) {
        tabs.forEach((tab, index) => {
          if ('' + tab.id == targetName) {
            let nextTab = tabs[index + 1] || tabs[index - 1];
            if (nextTab) {
              activeName = '' + nextTab.id;
            }
          }
        });
      }

      this.editableTabsValue = activeName;
      this.myLogFileList = tabs.filter(tab => '' + tab.id != targetName);
      if (this.myLogFileList.length == 0) {
        this.editableTabsValue = '-1';
      }
    },

    //打开任务的日志文件
    handleLogFile(row) {
      let idx = this.myLogFileList.findIndex(item => { return item.id == row.id });
      if (idx >= 0) {
        //this.editableTabsValue = '' + row.id;
        this.$set(this, 'editableTabsValue', '' + row.id);
      } else {
        let newLogFileTabPane = {};
        newLogFileTabPane.id = row.id;
        newLogFileTabPane.logFileName = row.logFileName;
        newLogFileTabPane.hostName = row.hostName;
        newLogFileTabPane.scheduleTime = row.scheduleTime;
        newLogFileTabPane.iconClass = "el-icon-loading";
        if (row.status == '2' || row.status == '8' || row.status == 'c' || row.status == 'w') {
          newLogFileTabPane.isRunning = true;
        } else {
          newLogFileTabPane.isRunning = false;
        }
        this.myLogFileList.push(newLogFileTabPane);
        this.$set(this, 'editableTabsValue', '' + row.id);
      }
    },

    checkCreateNewDisabled(status) {
      if (status == null) {
        return false;
      }
      const disableStatus = ['1', '2', '7', '8', '9', 'c', 'w'];
      let idx = disableStatus.findIndex(item => { return item == status });
      let ret = (idx >= 0);
      return ret;
    },

    handleListTaskBefore() {
      let param = {};
      param.jobId = this.myJob.id;
      param.recordCount = 10;
      param.operatorType = 'before';
      param.scheduleTime = this.myJob.taskProcesses[0].scheduleTime;
      this.listLoading = true;
      apiChildrenTaskList(param)
        .then(response => {
          this.listLoading = false;
          const data = response.data;
          if (data && data.length > 0) {
            this.myJob.taskProcesses.unshift(...(data));
          } else {
            this.$message({
              type: 'info',
              message: '没有更多数据了.',
              duration: 3000
            });
          }
        });
      this.listLoading = false;
    },

    handleListTaskAfter() {
      let param = {};
      param.jobId = this.myJob.id;
      param.recordCount = 10;
      param.operatorType = 'after';
      let lastIdx = this.myJob.taskProcesses.length - 1;
      param.scheduleTime = this.myJob.taskProcesses[lastIdx].scheduleTime;
      this.listLoading = true;
      apiChildrenTaskList(param)
        .then(response => {
          this.listLoading = false;
          const data = response.data;
          if (data && data.length > 0) {
            this.myJob.taskProcesses.push(...(data));
            let lastIdx = this.myJob.taskProcesses.length - 1;
            this.refreshEndTime = this.myJob.taskProcesses[lastIdx]['scheduleTime'];
          } else {
            this.$message({
              type: 'info',
              message: '没有更多数据了.',
              duration: 3000
            });
          }
        });
      this.listLoading = false;
    },

    handleJobGroupNewTask() {
      let param = {};
      param.id = this.myJob.id;
      apiTaskCreate(param)
        .then(response => {
          this.listLoading = false;
          const data = response.data;
          if (data) {
            //this.myJob.currentProcess = data;
            let idx = this.myJob.taskProcesses.findIndex(item => { return item.scheduleTime > data.scheduleTime });
            if (idx >= 0) {
              this.myJob.taskProcesses.splice(idx, 0, data);
            } else {
              this.myJob.taskProcesses.push(data);
            }
            this.messageSuccess();
            //this.callApiTaskCurrent();
          }
        });
    },

    handleJobGroupStopTask() {
      if (this.myJob.id == null || this.currentProcessId == null || this.currentProcessStatus == null) {
        this.$message({
          type: 'warning',
          message: '请更新一下当前状态.',
          duration: 3000
        });
        return;
      }
      let param = {};
      param.jobId = this.myJob.id;
      param.taskId = this.currentProcessId;
      param.status = this.currentProcessStatus;
      apiTaskGroupStop(param)
        .then(response => {
          this.listLoading = false;
          const data = response.data;
          if (data) {
            this.callApiTaskCurrentGroup();
          }
        });
    },

    getTaskProcessList(cfgJob) {
      if (cfgJob.taskProcesses == null || cfgJob.taskProcesses.length == 0) {
        let param = {};
        param.jobId = cfgJob.id;
        param.recordCount = 10;
        param.operatorType = 'current';
        this.listLoading = true;
        apiChildrenTaskList(param)
          .then(response => {
            const data = response.data;
            if (data) {
              this.$set(cfgJob, 'taskProcesses', data);
              let lastIdx = this.myJob.taskProcesses.length - 1;
              if (lastIdx >= 0) {
                this.refreshEndTime = this.myJob.taskProcesses[lastIdx]['scheduleTime'];
                this.callApiTaskCurrentGroup();
              }
            }
          });
      }
    },

    checkBoxRefreshChange(val) {
      if (val) {
        if (this.intervalReader) {
          clearInterval(this.intervalReader);
          this.intervalReader = null;
        }

        this.intervalReader = setInterval(() => {
          setTimeout(this.callApiTaskRefresh(), 0)
        }, 1000);
        this.$set(this.myJob, 'iconClass', "el-icon-loading");
        //this.myJob.iconClass = "el-icon-loading"
      }
      else {
        if (this.intervalReader) {
          clearInterval(this.intervalReader);
          this.intervalReader = null;
        }
        //this.myJob.iconClass = null;
        this.$set(this.myJob, 'iconClass', null);
      }
    },

    callApiTaskCurrentGroup() {
      let param = {};
      param.id = this.myJob.id;
      this.listLoading = true;
      apiTaskCurrentGroup(param)
        .then(response => {
          this.listLoading = false;
          const data = response.data;
          //console.log(data[0]);
          if (data) {
            this.$set(this, "currentProcessId", data[0].id);
            this.$set(this, "currentProcessStatus", data[0].status);
            let idx = this.myJob.taskProcesses.findIndex(item => { return item.id == data[0].id });
            this.myJob.taskProcesses.splice(idx, 1, data[0]);
          }
        });
      this.listLoading = false;
    },

    callApiTaskRefresh() {
      let lastIdx = this.myJob.taskProcesses.length - 1;
      if (lastIdx < 0) {
        return;
      }
      let param = {};
      param.jobId = this.myJob.id;
      if (null == this.refreshEndTime) {
        param.endTime = this.myJob.taskProcesses[lastIdx]['scheduleTime'];
      } else {
        param.endTime = this.refreshEndTime;
      }
      this.listLoading = true;
      apiTaskRefresh(param)
        .then(response => {
          this.listLoading = false;
          const data = response.data;
          //console.log(data[0]);
          if (data) {
            this.$set(this, "currentProcessId", data[0].id);
            this.$set(this, "currentProcessStatus", data[0].status);
            let idx = this.myJob.taskProcesses.findIndex(item => { return item.id == data[0].id });
            let howmany = this.myJob.taskProcesses.length - idx;
            this.myJob.taskProcesses.splice(idx, howmany);
            data.map(item => {
              if (item.parentId == item.id) {
                console.log("push:" + item);
                this.myJob.taskProcesses.push(item);
              } else {
                let parent = this.findParent(item.parentId, this.myJob.taskProcesses);
                if (null != parent) {
                  if (null == parent.children) {
                    parent.children = []
                    parent.children.push(item);
                  } else if (parent.children.length == 0) {
                    parent.children.push(item);
                  } else {
                    let idx = parent.children.findIndex(e => { return e.id == item.id });
                    if (idx >= 0) {
                      parent.children.splice(idx, 1, item);
                    } else {
                      parent.children.push(item);
                    }
                  }
                }
              }
            });

          }
        });
      this.listLoading = false;
    },

    findParent(parentId, tree) {
      if (tree == null || tree.length == 0) {
        return null;
      }
      for (let idx = 0; idx < tree.length; idx++) {
        if (tree[idx].id == parentId) {
          return tree[idx];
        } else {
          let parent = this.findParent(parentId, tree[idx].children);
          if (null != parent) {
            return parent;
          }
        }
      }
    }


  }
};
</script>

<style>
.c-Button {
  border: none;
  border-radius: 2px;
}

.c-Button--close {
  background-color: red;
}
</style>

<style module>
.button {
  border: none;
  border-radius: 2px;
}

.buttonClose {
  background-color: red;
}
</style>
